package com.regulareport.form.service.impl;

import com.regulareport.common.config.RuoYiConfig;
import com.regulareport.common.core.domain.entity.*;
import com.regulareport.common.enums.EnableStatus;
import com.regulareport.common.enums.MapStatus;
import com.regulareport.common.utils.RegularUtil;
import com.regulareport.common.utils.StringUtils;
import com.regulareport.common.utils.file.FileUploadUtils;
import com.regulareport.common.utils.poi.PoiUtil;
import com.regulareport.form.domain.*;
import com.regulareport.form.mapper.*;
import com.regulareport.form.service.IHeadIndexMapService;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileInputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class HeadIndexMapService implements IHeadIndexMapService {
    private static final Logger log = LoggerFactory.getLogger(HeadIndexMapService.class);

    @Autowired
    private ReportFormsEditMapper reportFormsEditMapper;

    @Autowired
    private HeadReportMapper headReportMapper;

    @Autowired
    private HeadIndexMapper headIndexMapper;

    @Autowired
    private HeadSubIndexMapMapper headSubIndexMapMapper;

    @Autowired
    private MapEditionMapper mapEditionMapper;


    @Transactional(rollbackFor = Throwable.class)
    @Override
    public void parse(MultipartFile file) throws Exception {
        //上传模块Begin
        //解析excel模板为byte数组
        byte[] fileBytes = null;
        try {
            fileBytes = file.getBytes();
        } catch (Exception e) {
            log.error("文件模板转换失败", e);
            //转换模板失败
            throw new Exception("文件模板转换失败");
        }

        if (fileBytes == null) {
            throw new Exception("文件模板无内容");
        }

        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 定义格式化模式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        // 格式化输出
        String formattedDate = currentDate.format(formatter);

        String uploadDir = RuoYiConfig.getUploadMasterPath() + "/" + formattedDate;
        String fileName = "";
        try {
            fileName = FileUploadUtils.uploadOriginalFile(uploadDir, file);
            log.info("总行模板{}，上传服务器成功", fileName);
        } catch (Exception e) {
            throw new Exception("模板上传服务器失败");
        }
        String absPath = uploadDir + "/" + file.getOriginalFilename();

        //查询需要映射的配置
        List<ReportFormsEditLocator> reportFormsEditLocators = reportFormsEditMapper.selectMaxReportEnable();
        for (ReportFormsEditLocator reportFormsEditLocator : reportFormsEditLocators) {
            String loc = reportFormsEditLocator.getLoc();
            if (StringUtils.isEmpty(loc)) {
                continue;
            }
            String[] split = loc.split(",|，");
            List<Locator> locators = new ArrayList<>();
            for (String array : split) {
                String[] sheetLoc = array.split("：|:");
                CellReference cellReference = new CellReference(sheetLoc[0]);
                Locator locator = new Locator();
                locator.setFirstRow(cellReference.getRow());
                locator.setFirstCol(cellReference.getCol());
                cellReference = new CellReference(sheetLoc[1]);
                locator.setLastRow(cellReference.getRow());
                locator.setLastCol(cellReference.getCol());
                locators.add(locator);
            }
            reportFormsEditLocator.setLocators(locators);
        }


        HeadReport headReport = headReportMapper.selectHeadReport(formattedDate);
        if (headReport != null) {
            headReport.setFilepath(absPath);
        } else {
            headReport = new HeadReport();
            headReport.setHeadEdition(formattedDate);
            headReport.setFilepath(absPath);
        }
        headReportMapper.insertHeadReport(headReport);

        try (FileInputStream fis = new FileInputStream(absPath)) {
            Workbook workbook = WorkbookFactory.create(fis);
            List<HeadIndex> headIndices = new ArrayList<>();
            for (ReportFormsEditLocator reportFormsEditLocator : reportFormsEditLocators) {
                System.out.println("reportFormsEditLocator SheName:" + reportFormsEditLocator.getSheetName());
                if (reportFormsEditLocator.getLocators() == null) {
                    continue;
                }
                for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                    String sheetName = workbook.getSheetName(i);
                    System.out.println("SheetName:" + sheetName);
                    String[] split1 = sheetName.split("_");
                    String headSheetName = split1[0];
                    if (headSheetName.equalsIgnoreCase(reportFormsEditLocator.getSheetName())) {
                        Sheet sheet = workbook.getSheet(sheetName);
                        List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
                        for (Locator locator : reportFormsEditLocator.getLocators()) {
                            for (int row = locator.getFirstRow(); row <= locator.getLastRow(); row++) {
                                List<String> name = new ArrayList<>();
                                for (int col = locator.getLastCol(); col >= locator.getFirstCol(); col--) {
                                    try {
                                        Cell cell = sheet.getRow(row).getCell(col);
                                        if (cell == null) break;
                                        boolean kk = false;
                                        for (CellRangeAddress mergedRegion : mergedRegions) {
                                            if (mergedRegion.isInRange(cell)) {
                                                kk = true;
                                                int row1 = mergedRegion.getFirstRow();
                                                col = mergedRegion.getFirstColumn();
                                                int colLast = mergedRegion.getLastColumn();
                                                if (col >= locator.getFirstCol() && colLast <= locator.getLastCol()) {
                                                    Cell cella = sheet.getRow(row1).getCell(col);
                                                    String valuea = PoiUtil.getCellValueAsString(cella);
                                                    if (!StringUtils.isEmpty(valuea)) {
                                                        name.add(RegularUtil.replaceKong(valuea));
                                                    }
                                                }
                                                break;
                                            }
                                        }
                                        if (!kk) {
                                            String value = PoiUtil.getCellValueAsString(cell);
                                            if (!StringUtils.isEmpty(value)) {
                                                if ("GF1900".equalsIgnoreCase(reportFormsEditLocator.getReportFormNo())) {
                                                    Cell cell1 = sheet.getRow(row).getCell(col + 1);
                                                    String valueaa = PoiUtil.getCellValueAsString(cell1);
                                                    name.add(RegularUtil.replaceKong(valueaa) + RegularUtil.replaceKong(value));
                                                } else {
                                                    name.add(RegularUtil.replaceKong(value));
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                        throw new Exception("Sheet页：" + sheetName + ",第 " + (row + 1) + " 行，第 " + (col + 1) + "列，解析失败");
                                    }
                                }

                                if (!name.isEmpty()) {
                                    HeadIndex headIndex = getHeadIndex(reportFormsEditLocator, name, headReport);
                                    headIndex.setRowN(row);
                                    headIndices.add(headIndex);
                                }
                            }
                        }
                    }
                }
            }
            List<HeadIndex> list = new ArrayList<>();
            for (int i = 0; i < headIndices.size(); i++) {
                list.add(headIndices.get(i));
                if (list.size() >= 500) {
                    headIndexMapper.insertHeadIndices(list);
                    list.clear();
                }
            }
            if (!list.isEmpty()) {
                headIndexMapper.insertHeadIndices(list);
                list.clear();
            }
            workbook.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }

        List<HeadIndex> judgeHeadIndex = headIndexMapper.selectHeadIndices(headReport.getHeadReportId());
        Map<String, List<HeadIndex>> judgeHeadIndexMap = judgeHeadIndex.stream()
                .collect(Collectors.groupingBy(HeadIndex::getSheetName));

        for (ReportFormsEditLocator reportFormsEdit : reportFormsEditLocators) {
            List<HeadIndex> judge = judgeHeadIndexMap.get(reportFormsEdit.getSheetName());
            if (judge == null || judge.isEmpty()) {
                continue;
            }

            String reportFormNo = reportFormsEdit.getReportFormNo();
            String edition = reportFormsEdit.getEdition();
            ReportTemplateProgramDefinition reportTemplateProgramDefinition = new ReportTemplateProgramDefinition();
            reportTemplateProgramDefinition.setReportFormNo(reportFormNo);
            reportTemplateProgramDefinition.setEdition(edition);
            reportTemplateProgramDefinition.setPkId(reportFormsEdit.getPkId());
            List<ReportTemplateProgramDefinition> reportTemplateProgramDefinitions = headReportMapper.selectTempMap(reportTemplateProgramDefinition);

            List<HeadSubIndexMap> headSubIndexMaps = new ArrayList<>();

            List<String> parsedStr = new ArrayList<>(judge.size());
            for (int i = 0; i < judge.size(); i++) {
                parsedStr.add(null);
            }
            for (ReportTemplateProgramDefinition templateProgramDefinition : reportTemplateProgramDefinitions) {
                String[] slave = templateProgramDefinition.getProgramName().split("_");
                String sla = RegularUtil.replaceKong(slave[slave.length - 1]);
                System.out.println("Slave:" + sla);
                HeadSubIndexMap headSubIndexMap = new HeadSubIndexMap();
                headSubIndexMap.setSubIndexId(templateProgramDefinition.getPkId());
                int findNum = 0;
                for (int i = 0; i < judge.size(); i++) {
                    HeadIndex headIndex = judge.get(i);
                    if (parsedStr.get(i) == null) {
                        String indexName = headIndex.getIndexName();
                        String[] slave1 = indexName.split("_");
                        String ma = slave1[slave1.length - 1];
                        parsedStr.add(i, ma);
                        System.out.println("master:" + ma);
                        if (ma.equals(sla)) {
                            findNum++;
                            headSubIndexMap.setHeadIndexId(headIndex.getHeadIndexId());
                            headSubIndexMap.setFromt(MapStatus.AUTO.getCode());
                        }
                    } else {
                        if (parsedStr.get(i).equals(sla)) {
                            findNum++;
                            headSubIndexMap.setHeadIndexId(headIndex.getHeadIndexId());
                            headSubIndexMap.setFromt(MapStatus.AUTO.getCode());
                        }
                    }
                }

                if (findNum > 1) {
                    System.out.println("重复");
                    headSubIndexMap.setHeadIndexId(null);
                    headSubIndexMap.setFromt(null);
                }
                headSubIndexMaps.add(headSubIndexMap);
            }

            if (!headSubIndexMaps.isEmpty()) {
                MapEdition mapEdition = new MapEdition();
                mapEdition.setMapEdition(formattedDate);
                mapEdition.setHeadReportId(headReport.getHeadReportId());
                mapEdition.setSubReportId(reportFormsEdit.getPkId());
                mapEdition.setSheetName(reportFormsEdit.getSheetName());
                List<MapEdition> mapEditions = mapEditionMapper.selectMapEditionByAll(mapEdition);
                if (mapEditions.isEmpty()) {
                    mapEdition.setEnable(EnableStatus.DISABLE.getCode());
                    mapEditionMapper.insertMapEdition(mapEdition);
                } else {
                    mapEdition = mapEditions.get(0);
                }

                for (HeadSubIndexMap headSubIndexMap : headSubIndexMaps) {
                    headSubIndexMap.setMapEditionId(mapEdition.getMapEditionId());
                }

                List<HeadSubIndexMap> list = new ArrayList<>();
                for (int i = 0; i < headSubIndexMaps.size(); i++) {
                    list.add(headSubIndexMaps.get(i));
                    if (list.size() >= 500) {
                        headSubIndexMapMapper.insertHeadSubIndexMaps(headSubIndexMaps);
                        list.clear();
                    }
                }
                if (!list.isEmpty()) {
                    headSubIndexMapMapper.insertHeadSubIndexMaps(headSubIndexMaps);
                    list.clear();
                }
            }
        }
    }

    private static HeadIndex getHeadIndex(ReportFormsEditLocator reportFormsEditLocator, List<String> name, HeadReport headReport) {
        HeadIndex headIndex = new HeadIndex();
        String indexName = name.get(0);
        String indexFull = "";
        for (int n = name.size(); n > 0; n--) {
            if (n == name.size()) {
                indexFull = name.get(n - 1);
            } else {
                indexFull = indexFull + "_" + name.get(n - 1);
            }
        }
        headIndex.setIndexFull(indexFull);
        headIndex.setIndexName(indexName);
        headIndex.setSheetName(reportFormsEditLocator.getSheetName());
        headIndex.setHeadReportId(headReport.getHeadReportId());
        return headIndex;
    }

    @Override
    public List<MapEditionListVO> mapEditionList(MapEditionListQuery query) {
        return mapEditionMapper.selectMapEditionList(query);
    }

    @Override
    public List<ReportHeadSubMapVo> mapList(HeadSubIndexMapQuery headSubIndexMapQuery) {
        Long mapEditionId = Long.valueOf(headSubIndexMapQuery.getMapEditionId());
        return headSubIndexMapMapper.selectMapListByMapEditionBySearchType(mapEditionId, headSubIndexMapQuery.getSearchType());
    }

    @Override
    public List<HeadIndexVO> notMapList(Long mapEditionId) {
        return headSubIndexMapMapper.notMapList(mapEditionId);
    }

    @Override
    public void edit(HeadSubIndexEdit headSubIndexEdit) {
        HeadSubIndexMap headSubIndexMap = new HeadSubIndexMap();
        headSubIndexMap.setMapEditionId(Long.valueOf(headSubIndexEdit.getMapEditionId()));
        if (!StringUtils.isEmpty(headSubIndexEdit.getHeadIndexId())) {
            headSubIndexMap.setHeadIndexId(Long.valueOf(headSubIndexEdit.getHeadIndexId()));
        }
        headSubIndexMap.setSubIndexId(Long.valueOf(headSubIndexEdit.getSubIndexId()));

        headSubIndexMap.setFromt(MapStatus.HAND.getCode());
        headSubIndexMapMapper.insertHeadSubIndexMaps(Arrays.asList(headSubIndexMap));
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void enable(NotMapListQuery notMapListQuery) {
        MapEdition mapEdition = new MapEdition();
        mapEdition.setMapEditionId(Long.valueOf(notMapListQuery.getMapEditionId()));
        List<MapEdition> mapEditions = mapEditionMapper.selectMapEditionByAll(mapEdition);
        MapEdition changeEntity = mapEditions.get(0);
        if (changeEntity.getEnable().equals(EnableStatus.OK.getCode())) { //启用--禁用
            MapEdition update = new MapEdition();
            update.setEnable(EnableStatus.DISABLE.getCode());
            update.setMapEditionId(changeEntity.getMapEditionId());
            mapEditionMapper.updateMapEditionEnable(update);
        } else {
            // 禁用 --启用
            MapEdition update = new MapEdition();
            update.setEnable(EnableStatus.DISABLE.getCode());
            update.setSubReportId(changeEntity.getSubReportId());
            // 关闭
            mapEditionMapper.updateMapEditionEnable(update);
            update = new MapEdition();
            update.setEnable(EnableStatus.OK.getCode());
            update.setMapEditionId(changeEntity.getMapEditionId());
            // 开启
            mapEditionMapper.updateMapEditionEnable(update);
        }
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void delete(NotMapListQuery notMapListQuery) {
        mapEditionMapper.deleteById(Long.valueOf(notMapListQuery.getMapEditionId()));
        headSubIndexMapMapper.deleteByMapEditionId(Long.valueOf(notMapListQuery.getMapEditionId()));
    }
}
